package com.wh.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import com.legend.security.PermissionType;
import com.wh.beans.Enum.UserTypeEnum;
import com.wh.beans.PathVariable.LoginParam;
import com.wh.beans.PathVariable.RegisterParam;
import com.wh.service.IExt.*;
import com.legend.utils.*;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.wh.beans.PathVariable.LoginInfo;
import com.wh.beans.LoginInfoCookie;
import com.wh.dao.BaseDao;
import com.wh.dao.ext.SysUserBaseDao;
import com.wh.model.BaseModel;
import com.wh.model.DailyNotebook;
import com.wh.model.SysRoleMenu;
import com.wh.model.SysRolePower;
import com.wh.model.SysUserBase;
import com.wh.model.SysUserMenu;
import com.wh.model.SysUserPower;


public class SysUserBaseService extends BaseServiceImp implements ISysUserBaseService {
    Logger log = Logger.getRootLogger();

    private SysUserBaseService() {
    }

    //volatile修饰的写变量不能和之前的读写代码调整，读变量不能和之后的读写代码调整
    private volatile static ISysUserBaseService instance = null;

    /**
     * 单例
     *
     * @return
     */
    public static ISysUserBaseService getInstance() {
        if (instance == null) {
            synchronized (ISysUserBaseService.class) {
                if (instance == null) {
                    instance = new SysUserBaseService();
                }
            }
        }
        return instance;
    }


    /**
     * 批量删除数据
     */
    public ReturnResult delByIds(String ids) {
        SqlSession session = getSqlSession();
        ReturnResult result = new ReturnResult();
        try {
            SysUserBaseDao dao = session.getMapper(SysUserBaseDao.class);
            result = delByMap(dao, ids);
        } catch (Exception ex) {
            log.error(ex.getMessage());
        } finally {
            session.close();
        }
        return result;
    }

    /**
     * 分页数据查询
     *
     * @param pageIndex
     * @param pageSize
     * @param map
     * @return
     */
    public ReturnResult selectByMap(int pageIndex, int pageSize, Map<String, Object> map) {
        SqlSession session = getSqlSession();
        SysUserBaseDao dao = session.getMapper(SysUserBaseDao.class);
        int recordNum = (pageIndex - 1) * pageSize;
        List<SysUserBase> lst = session.selectList(ConfigUtils.getInstance().getDaoPackage(".SysUserBaseDao.selectByMap"), map,
                new RowBounds(recordNum, pageSize));
        int total = dao.count(map);
        ReturnResult result = new ReturnResult();
        result.setMsg(i18nUtils.getVal("100001000"));
        result.setRows(lst);
        result.setTotal(total);
        result.setStatus(Status.SUCCESS);
        session.close();
        return result;
    }

    @Override
    public ReturnResult insertByModel(BaseModel model) {
        SqlSession session = getSqlSession();
        SysUserBaseDao dao = session.getMapper(SysUserBaseDao.class);
        ReturnResult result = insertByModel(dao, model);
        session.close();
        return result;
    }

    @Override
    public ReturnResult editByModel(BaseModel model) {
        SqlSession session = getSqlSession();
        SysUserBaseDao dao = session.getMapper(SysUserBaseDao.class);
        ReturnResult result = editByModel(dao, model);
        session.close();
        return result;
    }

    /**
     * 根据ID获取一条数据
     *
     * @param id
     * @return
     */
    public ReturnResult selectById(String id) {
        SqlSession session = getSqlSession();
        ReturnResult result = new ReturnResult();
        result.setStatus(Status.ERROR);
        BaseDao dao = session.getMapper(SysUserBaseDao.class);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("id", id);
        List<SysUserBase> lst = dao.selectByMap(map);
        if (lst.size() == 1) {
            result.setData(lst.get(0));
            result.setStatus(Status.SUCCESS);
        } else {
            result.setMsg(i18nUtils.getVal("100004000"));
        }
        session.close();
        return result;
    }

    /**
     * 批量审核数据
     */
    public ReturnResult audit(int state, String[] idArr) {
        SqlSession session = getSqlSession();
        SysUserBaseDao dao = session.getMapper(SysUserBaseDao.class);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("idArr", idArr);
        map.put("state", state);
        Integer num = dao.audit(map);
        ReturnResult result = new ReturnResult();
        if (num > 0) {
            result.setMsg(i18nUtils.getVal("100001000"));
            result.setStatus(Status.SUCCESS);
        }
        session.close();
        return result;
    }

    /**
     * 排序
     *
     * @param sorts
     * @param ids
     * @return
     */
    public ReturnResult sort(String sorts, String ids) {
        ReturnResult result;
        SqlSession session = getSqlSession();
        SysUserBaseDao dao = session.getMapper(SysUserBaseDao.class);
        result = sort(session, dao, sorts, ids);
        if (session != null)
            session.close();
        return result;
    }

    /**
     * 返回指定数据列表
     *
     * @param map
     * @return
     */
    public List<SysUserBase> select(Map<String, Object> map) {
        SqlSession session = getSqlSession();
        SysUserBaseDao dao = session.getMapper(SysUserBaseDao.class);
        List<SysUserBase> lst = dao.selectByMap(map);
        session.close();
        return lst;
    }

    /**
     * 总数
     *
     * @param map
     * @return
     */
    public int count(Map<String, Object> map) {
        SqlSession session = getSqlSession();
        SysUserBaseDao dao = session.getMapper(SysUserBaseDao.class);
        int count = dao.count(map);
        session.close();
        return count;
    }

    /**
     * 用户登录
     *
     * @param info
     * @return 如果成功返回的data包含用户信息
     */
    public ReturnResult userLogin(LoginInfo info) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("userAccount", info.getUserAccount());
        param.put("userPassword", StringUtils.md5(info.getUserPassword()));
        ReturnResult result = new ReturnResult();
        result.setStatus(Status.ERROR);
        List<SysUserBase> lst = select(param);
        // Map<String, Object> userMap = new HashMap<String, Object>();
        if (lst.size() == 1) {
            log.debug(lst.size() + "ssssssssssssssssssssssssssssss");
            SysUserBase model = lst.get(0);
            LoginInfoCookie loginCookie = new LoginInfoCookie();
            if (model.getStatus().equals(1)) {
                loginCookie.setUseNotebook(model.getUseNotebook());
                // 初始化用户角色
                String userId = model.getId();
                ISysUserRoleService surBo =  SysUserRoleService.getInstance();
                result = surBo.currentUserSubRole(userId);
                if (result.getStatus() == Status.SUCCESS)
                    loginCookie.setSubRole(result.getData().toString());
                else {
                    return result;
                }
                ISysRoleService srBo =  SysRoleService.getInstance();
                result = srBo.selectById(model.getRoleId());
                if (result.getStatus() == Status.SUCCESS)
                    loginCookie.setRoleName(result.getData().toString());
                else {
                    return result;
                }
                // 初始化菜单
                ISysUserMenuService sumBo = SysUserMenuService.getInstance();
                List<String> userMenuLst = new ArrayList<String>();// 直属用户的栏目ID列表
                result = sumBo.currentUserSubMenu(userId);
                if (result.getStatus() == Status.SUCCESS) {
                    @SuppressWarnings("unchecked")
                    List<SysUserMenu> sumLst = (List<SysUserMenu>) result.getRows();
                    for (SysUserMenu sum : sumLst) {
                        userMenuLst.add(sum.getMenuId());
                    }
                } else
                    return result;
                ISysUserMenuService bo = SysUserMenuService.getInstance();

                result = bo.currentRoleSubMenu(model.getId());
                if (result.getStatus() == Status.SUCCESS) {
                    @SuppressWarnings("unchecked")
                    List<SysRoleMenu> srmLst = (List<SysRoleMenu>) result.getRows();// 属用户所属角色下的栏目ID列表
                    if (userMenuLst.size() > 0) {
                        for (SysRoleMenu srm : srmLst) {
                            if (!userMenuLst.contains(srm.getMenuId())) {
                                userMenuLst.add(srm.getMenuId());
                            }
                        }
                    } else {
                        for (SysRoleMenu srm : srmLst) {
                            userMenuLst.add(srm.getMenuId());
                        }
                    }
                    // userMap.put("subMenu",JSONObject.toJSONString(mLst));
                    loginCookie.setSubMenu(JSONObject.toJSONString(userMenuLst));
                } else
                    return result;

                // 用户操作权限
                ISysUserPowerService supBo =  SysUserPowerService.getInstance();
                result = supBo.userPower(userId);
                if (result.getStatus() == Status.SUCCESS) {
                    @SuppressWarnings("unchecked")
                    List<SysUserPower> supLst = (List<SysUserPower>) result.getRows(); // 用户直接拥有的操作权限
                    Map<String, Integer> supMap = new HashMap<String, Integer>();
                    for (SysUserPower sysUserPower : supLst) {
                        supMap.put(sysUserPower.getModuleCode(), sysUserPower.getPowerValue());
                    }
                    loginCookie.setUserPower(JSONObject.toJSONString(supMap));
                    ISysRolePowerService rpbo =  SysRolePowerService.getInstance();
                    result = rpbo.rolePower(model.getRoleId());// 通过角色继承的权限
                    if (result.getStatus() == Status.SUCCESS) {
                        Map<String, Integer> map = new HashMap<String, Integer>();
                        @SuppressWarnings("unchecked")
                        List<SysRolePower> rplst = (List<SysRolePower>) result.getRows();
                        for (SysRolePower srpr : rplst) {
                            map.put(srpr.getModuleCode(), srpr.getPowerValue());
                        }
                        // SessionUtils.getInstance().set(ConstVar.SYSROLEPOWER_SESSIONKEY,
                        // map);
                        // userMap.put("rolePower",
                        // JSONObject.toJSONString(map));
                        loginCookie.setRolePower(JSONObject.toJSONString(map));
                        // result.setMsg("初始化角色与用户操作权限成功!");
                    } else
                        return result;
                } else
                    return result;
                // userMap.put("userId", model.getId());
                // userMap.put("userAccount", model.getUserAccount());
                // userMap.put("isSuper", 0);
                loginCookie.setUserId(model.getId());
                loginCookie.setIsSuper(0);
                loginCookie.setUserAccount(model.getUserAccount());
                result.setStatus(Status.SUCCESS);
                result.setData(loginCookie);
                result.setMsg(i18nUtils.getVal("200004002"));
            } else {
                result.setMsg(i18nUtils.getVal("200001003"));
            }
        } else {
            result.setMsg(i18nUtils.getVal("200001004"));
        }
        return result;
    }

    /**
     * work用户登录
     *
     * @param user
     * @param userType
     * @return
     */
    @Override
    public ReturnResult userLogin(LoginParam user, UserTypeEnum userType) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("userAccount", user.getUserName());
        param.put("userPassword",StringUtils.md5(user.getPassword()));
        ReturnResult result = new ReturnResult();
        result.setStatus(Status.ERROR);
        List<SysUserBase> lst = select(param);
        if (lst.size() == 1) {
            SysUserBase userBase = lst.get(0);
            if (userBase.getStatus() == 0) {
                result.setMsg(i18nUtils.getVal("200001003"));
            } else if ((userBase.getUserType() & userType.getValue()) == userType.getValue()) {
                result.setStatus(Status.SUCCESS);
                LoginInfoCookie loginCookie = new LoginInfoCookie();
                loginCookie.setUserAccount(userBase.getUserAccount());
                loginCookie.setUserId(userBase.getId());
                result.setData(loginCookie);
                result.setMsg(i18nUtils.getVal("200004002"));
            } else {
                result.setMsg(i18nUtils.getVal("200004003"));
            }
        } else {
            result.setMsg(i18nUtils.getVal("200004004"));
        }
        return result;
    }

    /**
     * 打开记事本功能
     *
     * @param info
     * @return
     */
    @Override
    public ReturnResult openNotebook(LoginInfo info) {
        ReturnResult result = new ReturnResult();
        result.setStatus(Status.ERROR);
        if (StringUtils.isEmpty(info.getUserAccount())) {
            result.setMsg(i18nUtils.getVal("200001001"));
        } else if (StringUtils.isEmpty(info.getUserPassword())) {
            result.setMsg(i18nUtils.getVal("200001001"));
        } else {
            Map<String, Object> param = new HashMap<String, Object>();
            param.put("userAccount", info.getUserAccount());
            param.put("userPassword", StringUtils.md5(info.getUserPassword()));
            // param.put("useNotebook", 0);
            List<SysUserBase> users = select(param);
            if (users != null && users.size() == 1) {
                SysUserBase user = users.get(0);
                if (user.getStatus().equals(1)) {
                    if (user.getUseNotebook().equals(0)) {
                        SysUserBase userBase = new SysUserBase();
                        userBase.setId(user.getId());
                        userBase.setUseNotebook(1);
                        param = new HashMap<String, Object>();
                        param.put("id", user.getId());
                        param.put("useNotebook", 1);
                        result = editByModel(userBase);
                        if (result.getStatus().equals(Status.SUCCESS)) {
                            IDailyNotebookService nbBo =  DailyNotebookService.getInstance();
                            DailyNotebook notebook = new DailyNotebook();
                            notebook.setBookGroupId("0");
                            notebook.setBookName("默认笔记本");
                            Date date = new Date();
                            notebook.setCreateDate(date);
                            notebook.setGuid(UUID.randomUUID().toString());
                            notebook.setReadPassword("");
                            notebook.setSort(0);
                            notebook.setStatus(1);
                            notebook.setSysDefault(1);
                            notebook.setTheDefault(1);
                            notebook.setUpdateDate(date);
                            notebook.setUserId(user.getId());
                            result = nbBo.insertByModel(notebook);
                            if (result.getStatus().equals(Status.SUCCESS)) {
                                result.setMsg(i18nUtils.getVal("100001000"));
                            }
                        }
                    } else {
                        result.setStatus(Status.SUCCESS);
                        result.setMsg(i18nUtils.getVal("100001000"));
                    }
                } else {
                    result.setMsg(i18nUtils.getVal("200001003"));
                    result.setStatus(Status.ERROR);
                }
            } else {
                result.setMsg(i18nUtils.getVal("200001004"));
                result.setStatus(Status.ERROR);
            }
        }
        return result;
    }

    /**
     * 检查用户是否有当前模块权限
     *
     * @param
     * @param moduleCode
     * @param request
     * @return ReturnResult
     */
    public ReturnResult checkPower(PermissionType[] pts, String moduleCode, HttpServletRequest request) {
        ReturnResult result = new ReturnResult();
        result.setStatus(Status.NOLOGIN);
        // int currentValue = pt.getValue();
        // Object oUser =
        // SessionUtils.getInstance().get(ConstVar.SYSUSER_SESSIONKEY);
        LoginInfoCookie loginCookie = CommonBo.getInstance().checkLogin(request);
        if (loginCookie != null) {
            Map<String, Integer> oRolePowerMap = JSONObject.parseObject(loginCookie.getRolePower(),
                    new TypeReference<Map<String, Integer>>() {
                    });
            if (oRolePowerMap.containsKey(moduleCode)) {
                for (PermissionType pt : pts) {
                    if ((oRolePowerMap.get(moduleCode) & pt.getValue()) == pt.getValue()) {
                        result.setStatus(Status.SUCCESS);
                        return result;
                    }
                }
            }
            Map<String, Integer> oUserPowerMap = JSONObject.parseObject(loginCookie.getUserPower(),
                    new TypeReference<Map<String, Integer>>() {
                    });

            if (oUserPowerMap.containsKey(moduleCode)) {
                int powerValue = oUserPowerMap.get(moduleCode);
                for (PermissionType pt : pts) {
                    if ((powerValue & pt.getValue()) == pt.getValue()) {
                        result.setStatus(Status.SUCCESS);
                        return result;
                    }
                }
            }
            result = StringUtils.noPower();
        } else {
            result = StringUtils.noLogin();
        }
        return result;
    }

    @Override
    public ReturnResult register(RegisterParam param, UserTypeEnum userType) {
        ReturnResult result = new ReturnResult();
        if(""==param.getUserName())
        {
            result.setMsg(i18nUtils.getVal("200001001"));
            return result;
        }
        String password = param.getPassword() != null ? param.getPassword() : "";
        String rpassword = param.getRpassword() != null ? param.getRpassword() : "";
        if (""!=password&& password.equals(rpassword)) {
            SysUserBase userBase = new SysUserBase();
            userBase.setUserAccount(param.getUserName());
            userBase.setUserEmail(param.getEmail());
            userBase.setUserName(param.getUserName());
            SqlSession session = getSqlSession();
            SysUserBaseDao dao = session.getMapper(SysUserBaseDao.class);
            int count = dao.checkUser(userBase);
            if (count == 0) {
                userBase.setUserType(userType.getValue());
                userBase.setLoginIp(StringUtils.getIP());
                userBase.setRoleId("0");
                userBase.setUseNotebook(0);
                userBase.setUserAccount(param.getUserName());
                userBase.setUserName(param.getUserName());
                userBase.setUserEmail(param.getEmail());
                userBase.setUserPassword(StringUtils.md5(password));
                userBase.setCreateDate(new Date());
                userBase.setSort(0);
                userBase.setStatus(1);
                userBase.setUpdateDate(new Date());
                result = insertByModel(userBase);
                if (result.getStatus().equals(Status.SUCCESS)) {
                    result.setMsg(i18nUtils.getVal("200001011"));
                }
            } else {
                result.setMsg(i18nUtils.getVal("200001010"));
                result.setStatus(Status.ERROR);
            }
            session.close();
        } else if (!password.equals(rpassword)) {
            result.setMsg(i18nUtils.getVal("200002004"));
            result.setStatus(Status.ERROR);
        } else {
            result.setMsg(i18nUtils.getVal("100007000"));
            result.setStatus(Status.ERROR);
        }

        return result;
    }


}
